package com.google.code.memoriesalbum.service;

import java.io.IOException;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.slim3.datastore.Datastore;

import appengine.util.MemcacheUtil;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.code.memoriesalbum.meta.PicasaAlbumMeta;
import com.google.code.memoriesalbum.model.Account;
import com.google.code.memoriesalbum.model.PicasaAlbum;
import com.google.code.memoriesalbum.util.Constants;
import com.google.code.memoriesalbum.util.PicasaUtil;
import com.google.gdata.client.authn.oauth.OAuthException;
import com.google.gdata.client.photos.PicasawebService;
import com.google.gdata.util.ServiceException;

/**
 * {@link PicasaAlbum}を操作するためのサービスクラス。
 * @author shin1ogawa
 */
public class AlbumService {

	static PicasaAlbumMeta meta = PicasaAlbumMeta.get();


	/**
	 * {@link PicasawebService}を利用してアルバム一覧を取得し、Datastoreに格納する。
	 * @param accountKey
	 * @return {@link PicasaAlbum}のリスト
	 * @throws OAuthException
	 * @throws IOException
	 * @throws ServiceException
	 */
	public static List<PicasaAlbum> fetchAlbumList(Key accountKey) throws OAuthException,
			IOException, ServiceException {
		String accountKeyString = KeyFactory.keyToString(accountKey);
		deleteAlbumEntities(accountKey);

		Account account = Datastore.get(Account.class, accountKey);
		PicasawebService service = new PicasawebService(Constants.APPLICATION_NAME);
		PicasaUtil.setOAuthCredentials(service, account.getToken(), account.getTokenSecret());
		List<PicasaAlbum> albumList = PicasaUtil.getAlbumList(service, accountKey.getName());
		for (PicasaAlbum picasaAlbum : albumList) {
			picasaAlbum.setAccountKey(accountKey);
		}
		Datastore.put(albumList);
		MemcacheUtil.delete(Constants.CACHEKEY_PREFIX_ALBUMLIST + accountKeyString);
		return albumList;
	}

	/**
	 * @param accountKey
	 * @return 指定されたaccountのalbumのリスト
	 * @throws OAuthException 
	 * @throws ServiceException 
	 * @throws IOException 
	 */
	public static List<PicasaAlbum> getAlbumList(Key accountKey) throws OAuthException,
			IOException, ServiceException {
		String accountKeyString = KeyFactory.keyToString(accountKey);
		String memcacheKey = Constants.CACHEKEY_PREFIX_ALBUMLIST + accountKeyString;
		@SuppressWarnings("unchecked")
		List<PicasaAlbum> list = MemcacheUtil.get(memcacheKey, List.class);
		if (list != null) {
			return list;
		}
		list =
				Datastore.query(meta).filter(meta.accountKey.equal(accountKey))
					.sort(meta.date.desc).asList();
		if (CollectionUtils.isEmpty(list)) {
			// まだフェッチしていない？
			Account account = Datastore.get(Account.class, accountKey);
			PicasawebService service = new PicasawebService(Constants.APPLICATION_NAME);
			PicasaUtil.setOAuthCredentials(service, account.getToken(), account.getTokenSecret());
			list = PicasaUtil.getAlbumList(service, account.getEmail());
			for (PicasaAlbum picasaAlbum : list) {
				picasaAlbum.setAccountKey(accountKey);
			}
			Datastore.put(list);
		}
		MemcacheUtil.put(memcacheKey, list);
		return list;
	}

	static void deleteAlbumEntities(Key accountKey) {
		PicasaAlbumMeta meta = PicasaAlbumMeta.get();
		List<Key> keyList =
				Datastore.query(meta).filter(meta.accountKey.equal(accountKey)).asKeyList();
		Datastore.delete(keyList);
	}
}
